package com.itmk.web.wxapi.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itmk.utils.ResultUtils;
import com.itmk.utils.ResultVo;
import com.itmk.web.back_out.entity.BackOut;
import com.itmk.web.back_out.service.BackOutService;
import com.itmk.web.notice.entity.Notice;
import com.itmk.web.notice.service.NoticeService;
import com.itmk.web.room.entity.Room;
import com.itmk.web.room.entity.RoomPage;
import com.itmk.web.room.service.RoomService;
import com.itmk.web.room_category.entity.RoomCategory;
import com.itmk.web.room_category.service.RoomCategoryService;
import com.itmk.web.room_seat.entity.RoomSeat;
import com.itmk.web.room_seat.service.RoomSeatService;
import com.itmk.web.select_seat.entity.SelectSeat;
import com.itmk.web.select_seat.entity.SignParm;
import com.itmk.web.select_seat.service.SelectSeatService;
import com.itmk.web.sys_class.entity.SysClass;
import com.itmk.web.sys_class.service.SysClassService;
import com.itmk.web.sys_lost.entity.SysLost;
import com.itmk.web.sys_lost.service.SysLostService;
import com.itmk.web.sys_student.entity.SysStudent;
import com.itmk.web.sys_student.service.SysStudentService;
import com.itmk.web.sys_suggestion.entity.SysSuggestion;
import com.itmk.web.sys_suggestion.service.SysSuggestionService;
import com.itmk.web.wxapi.entity.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

 /**
 * @Author zhuqianying
 */
@RestController
@RequestMapping("/wxapi/allApi")
public class WxApiController {
    @Autowired
    private RoomCategoryService roomCategoryService;
    @Autowired
    private RoomService roomService;
    @Autowired
    private SysLostService sysLostService;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private SysStudentService sysStudentService;
    @Autowired
    private SysClassService sysClassService;
    @Autowired
    private SelectSeatService selectSeatService;
    @Autowired
    private RoomSeatService roomSeatService;
    @Autowired
    private BackOutService backOutService;
    @Autowired
    private SysSuggestionService sysSuggestionService;


    //公告
    @GetMapping("/getHomeNoticeList")
    public ResultVo getHomeNoticeList(){
        QueryWrapper<Notice> query = new QueryWrapper<>();
        query.lambda().orderByDesc(Notice::getCreateTime).last(" limit 3");
        List<Notice> list = noticeService.list(query);
        return ResultUtils.success("查询成功",list);
    }


    //最受欢迎预览室
    @GetMapping("/getHotRoom")
    public ResultVo getHotRoom(){
        List<EchartsItem> list = selectSeatService.getHotRoom();
        return ResultUtils.success("查询成功",list);
    }


    //每月预约总数统计
    @GetMapping("/getTotalMonth")
    public ResultVo getTotalMonth(){
        List<EchartsItem> category = selectSeatService.getTotalMonth();
        //组装数据
        Echart echart = new Echart();
        List<String> names = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        if(category.size()>0){
            for (int i=0;i<category.size();i++){
                names.add(category.get(i).getName());
                values.add(category.get(i).getValue());
            }
        }
        echart.setNames(names);
        echart.setValues(values);
        return ResultUtils.success("查询成功",echart);
    }
    //首页总数统计
    @GetMapping("/getTotal")
    public ResultVo getTotal(){
        TotalVo totalVo = new TotalVo();
        //班级总数
        int classCount = sysClassService.count();
        totalVo.setClassCount(classCount);
        //学生总数
        int stuCount = sysStudentService.count();
        totalVo.setStuCount(stuCount);
        //预览室总数
        int roomCount = roomService.count();
        totalVo.setRoomCount(roomCount);
        //反馈总数
        int suggestionCount = sysSuggestionService.count();
        totalVo.setSuggestCount(suggestionCount);
        return ResultUtils.success("查询成功",totalVo);
    }

    //修改密码
    @PostMapping("/updatePassword")
    public ResultVo updatePassword(@RequestBody UpdatePasswordParm parm){
        //根据id查询学生信息
        SysStudent student = sysStudentService.getById(parm.getUserId());
        if(!parm.getOldPassword().equals(student.getPassword())){
            return ResultUtils.error("原密码不正确!");
        }
        SysStudent sysStudent = new SysStudent();
        sysStudent.setStuId(parm.getUserId());
        sysStudent.setPassword(parm.getPassword());
        if(sysStudentService.updateById(sysStudent)){
            return ResultUtils.success("修改成功!");
        }
        return ResultUtils.error("修改失败!");
    }

    //新增意见反馈
    @PostMapping("/addSuggestion")
    public ResultVo addSuggestion(@RequestBody SysSuggestion sysSuggestion){
        sysSuggestion.setCreateTime(LocalDateTime.now());
        if(sysSuggestionService.save(sysSuggestion)){
            return ResultUtils.success("新增成功!");
        }
        return ResultUtils.error("新增失败!");
    }

    //查询我的预约记录列表
    @GetMapping("/getMySeatHistryList")
    public ResultVo getMySeatHistryList(SeatListParm parm){
        IPage<BackOut> page = new Page<>(parm.getCurrentPage(),parm.getPageSize());
        QueryWrapper<BackOut> query = new QueryWrapper<>();
        query.lambda().eq(BackOut::getStuId,parm.getStuId()).orderByDesc(BackOut::getOrderTime);
        IPage<BackOut> list = backOutService.page(page,query);
        return ResultUtils.success("查询成功",list);
    }
    //签退
    @PostMapping("/signOut")
    public ResultVo signOut(@RequestBody SignParm signParm){
        //判断签退时间，是否在关门时间之前
        SelectSeat selectSeat = selectSeatService.getById(signParm.getSelectId());
        //查询图书馆关门时间
        Room room = roomService.getById(selectSeat.getRoomId());
        //获取预约时间
        LocalDateTime seatOrderTime = selectSeat.getOrderTime();
        //获取预约时间的 年 月 日
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = seatOrderTime.format(formatter);
        //获取关门时间 时分秒
        DateTimeFormatter hourFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        String formattedTime = room.getEndTime().format(hourFormatter);
        // 预约时间  年 月 日 + 关门时间  时分秒 = 关店时间
        String colseString = format + " " + formattedTime;
        DateTimeFormatter colseForm = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //得到关店时间
        LocalDateTime closeTime = LocalDateTime.parse(colseString, colseForm);

        LocalDateTime currentTime = LocalDateTime.now();

        if(currentTime.isBefore(closeTime) || currentTime.isEqual(closeTime)){ //关门时间之前：正常签退
            signParm.setStatus("3");
            selectSeatService.signOut(signParm);
            return ResultUtils.success("签退成功！");
        }else{ //漏签: 超时签退
            signParm.setStatus("4");
            signParm.setLastTime(closeTime);
            selectSeatService.signOut(signParm);
            return ResultUtils.success("签退成功【漏签退】！");
        }

    }

    //签到
    @PostMapping("/sign")
    public ResultVo sign(@RequestBody SignParm signParm){
        //判断是否在预约时间开始前半小时内
        LocalDateTime currentTime = LocalDateTime.now();
        SelectSeat seat = selectSeatService.getById(signParm.getSelectId());
        LocalDateTime firstTime = seat.getFirstTime();
        LocalDateTime lastTime = seat.getLastTime();
        if(currentTime.isBefore(firstTime)){ //未到签到时间
            return ResultUtils.error("未到签到时间，不能签到！");
        }else if(currentTime.isAfter(lastTime)){ //迟到签到
            signParm.setStatus("2");
            selectSeatService.signSeat(signParm);
            return ResultUtils.success("迟到签到！");
        }else{ //时间范围内签到
            signParm.setStatus("1");
            selectSeatService.signSeat(signParm);
            return ResultUtils.success("签到成功！");
        }

    }

    //取消预约  1:已预约 2：已签到 3：已签退4：已取消
    @PostMapping("/cancel")
    public ResultVo cancel(@RequestBody SelectSeat selectSeat){
        UpdateWrapper<SelectSeat> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(SelectSeat::getStatus,"4").set(SelectSeat::getUseStatus,"0")
                .eq(SelectSeat::getSelectId,selectSeat.getSelectId());
        if(selectSeatService.update(updateWrapper)){
            return ResultUtils.success("取消成功!");
        }
        return ResultUtils.error("取消失败!");
    }

    //查询我的预约列表
    @GetMapping("/getMySeatList")
    public ResultVo getMySeatList(SeatListParm parm){
        IPage<SelectSeat> page = new Page<>(parm.getCurrentPage(),parm.getPageSize());
        QueryWrapper<SelectSeat> query = new QueryWrapper<>();
        query.lambda().eq(SelectSeat::getStuId,parm.getStuId()).orderByDesc(SelectSeat::getOrderTime);
        IPage<SelectSeat> list = selectSeatService.page(page,query);
        return ResultUtils.success("查询成功",list);
    }
    //根据id查询学生信息
    @GetMapping("/getStuById")
    public ResultVo getStuById(Integer stuId){
        SysStudent student = sysStudentService.getById(stuId);
        return ResultUtils.success("查询成功",student);
    }
    //更新学生信息
    @PostMapping("/updateStuById")
    public ResultVo updateStuById(@RequestBody SysStudent student){
        if(sysStudentService.updateById(student)){
            return ResultUtils.success("修改成功");
        }
        return ResultUtils.error("修改失败");
    }
    //小程序首页分类数据
    @GetMapping("/getIndexCategory")
    public ResultVo getIndexCategory(){
        QueryWrapper<RoomCategory> query = new QueryWrapper<>();
        query.lambda().orderByAsc(RoomCategory::getOrderNum);
        List<RoomCategory> list = roomCategoryService.list(query);
        return ResultUtils.success("查询成功",list);
    }

    //小程序首页列表
    @GetMapping("/getIndex")
    public ResultVo getIndex(RoomPage parm){
        IPage<Room> list = roomService.getIndexList(parm);
        return ResultUtils.success("查询成功",list);
    }

    //失物招领
    @GetMapping("/getLostList")
    public ResultVo getLostList(LostParm parm){
        //构造分页对象
        IPage<SysLost> page = new Page<>(parm.getCurrentPage(),parm.getPageSize());
        //构造查询条件
        QueryWrapper<SysLost> query = new QueryWrapper<>();
        query.lambda().eq(SysLost::getType,parm.getType())
                .eq(SysLost::getStatus,"0")
                .orderByDesc(SysLost::getCteateTime);
        IPage<SysLost> list = sysLostService.page(page, query);
        return ResultUtils.success("查询成功",list);
    }

    //公告列表
    @GetMapping("/getNoticeList")
    public ResultVo getNoticeList(LostParm parm){
        //构造分页对象
        IPage<Notice> page = new Page<>(parm.getCurrentPage(),parm.getPageSize());
        //构造查询条件
        QueryWrapper<Notice> query = new QueryWrapper<>();
                query.lambda().orderByDesc(Notice::getCreateTime);
        IPage<Notice> list = noticeService.page(page, query);
        return ResultUtils.success("查询成功",list);
    }

    //小程序登录
    @PostMapping("/login")
    public ResultVo login(@RequestBody SysStudent student){
        QueryWrapper<SysStudent> query = new QueryWrapper<>();
        query.lambda().eq(SysStudent::getStuNum,student.getStuNum())
                .eq(SysStudent::getPassword,student.getPassword());
        SysStudent one = sysStudentService.getOne(query);
        if(one == null){
            return ResultUtils.error("账号或密码错误!");
        }
        return ResultUtils.success("登录成功",one.getStuId());
    }
    //查询班级下拉列表
    @GetMapping("/getClassesList")
    public ResultVo getClassesList(){
        QueryWrapper<SysClass> query = new QueryWrapper<>();
        query.lambda().orderByDesc(SysClass::getOrderNum);
        List<SysClass> list = sysClassService.list(query);
        //返回的组装数据
        List<ClassVo> classVoList = new ArrayList<>();
        Optional.ofNullable(list).orElse(new ArrayList<>())
                .stream()
                .forEach(item ->{
                    ClassVo vo  =  new ClassVo();
                    vo.setClassId(item.getClassId());
                    vo.setName(item.getClassName());
                    classVoList.add(vo);
                });
        return ResultUtils.success("查询成功",classVoList);
    }

    //注册
    @PostMapping("/register")
    public ResultVo register(@RequestBody RegisterParm parm){
        //查询学生是否存在
        QueryWrapper<SysStudent> query = new QueryWrapper<>();
        query.lambda().eq(SysStudent::getClassId,parm.getClassId())
                .eq(SysStudent::getStuNum,parm.getStuNum());
        SysStudent one = sysStudentService.getOne(query);
        if(one == null){
            return ResultUtils.error("您不是本校学生，不能注册!");
        }
        //更新密码
        UpdateWrapper<SysStudent> up = new UpdateWrapper<>();
        up.lambda().set(SysStudent::getPassword,parm.getPassword())
                .eq(SysStudent::getStuId,one.getStuId());
        if(sysStudentService.update(up)){
            return ResultUtils.success("注册成功!");
        }
        return ResultUtils.error("注册失败!");
    }

    //预约保存
    @PostMapping("/selectSeatSave")
    public ResultVo selectSeatSave(@RequestBody SelectSeat selectSeat){
        //查询当月违约记录是否超过3次
        List<BackOut> backList = backOutService.getBackList(selectSeat.getStuId());
        if(backList.size() >3){
            return ResultUtils.error("本月已违约3次，无法预约座位！");
        }
        //判断是否有未签到和签退的预约
        QueryWrapper<SelectSeat> queryStatus = new QueryWrapper<>();
        String[] statusin = {"1","2"};
        queryStatus.lambda().eq(SelectSeat::getStuId,selectSeat.getStuId()).in(SelectSeat::getStatus,statusin);
        List<SelectSeat> list = selectSeatService.list(queryStatus);
        if(!list.isEmpty()){
            return ResultUtils.error("您存在未签到或者签退的预约，请先签到或者签退!");
        }
        //判断预约时间是否在营业时间范围内预约
        LocalDateTime seatOrderTime = selectSeat.getOrderTime();
        if(seatOrderTime.isBefore(selectSeat.getBeginTime()) || seatOrderTime.isAfter(selectSeat.getCreateTime())){
            return ResultUtils.error("预约时间不在营业时间范围内！");
        }
        //根据roomId和seatId判断是否已经被使用
        QueryWrapper<SelectSeat> query = new QueryWrapper<>();
        query.lambda().eq(SelectSeat::getRoomId,selectSeat.getRoomId())
                .eq(SelectSeat::getSeatId,selectSeat.getSeatId())
                .eq(SelectSeat::getUseStatus,"1");
        SelectSeat one = selectSeatService.getOne(query);
        if(one != null){
            return ResultUtils.error("【"+selectSeat.getSeatName()+"】座位已经被预约使用");
        }
        //预约时间
        LocalDateTime orderTime = selectSeat.getOrderTime();
        //设置最早签到时间
        selectSeat.setFirstTime(orderTime.minusMinutes(30));
        //设置最迟签到时间
        selectSeat.setLastTime(orderTime.plusMinutes(30));

        selectSeat.setUseStatus("1");
        selectSeat.setStatus("1");
        if(selectSeatService.save(selectSeat)){
            return ResultUtils.success("预约成功!");
        }
        return ResultUtils.error("预约失败!");
    }

    //查询图书馆座位
    @GetMapping("/getSeatList")
    public ResultVo getSeatList(Integer roomId){
        //查询预览室下面的所有座位
        QueryWrapper<RoomSeat> query = new QueryWrapper<>();
        query.lambda().eq(RoomSeat::getRoomId,roomId);
        List<RoomSeat> seatList = roomSeatService.list(query);
        //查询预览室下面被使用的座位
        QueryWrapper<SelectSeat> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SelectSeat::getUseStatus,"1");
        List<SelectSeat> list = selectSeatService.list(queryWrapper);
        if(list.size() > 0){
            for (int i = 0;i<list.size();i++){
                for (int j =0;j<seatList.size();j++){
                    //查询哪些座位被选了
                    if(list.get(i).getSeatId().equals(seatList.get(j).getSeatId())){
                        seatList.get(j).setHasSelect("1");
                        seatList.get(j).setSelect(true);
                    }
                }
            }
        }
        return ResultUtils.success("查询成功",seatList);
    }
}
